package util;

import java.util.List;
import java.util.function.Function;

import static java.util.stream.Collectors.toList;

/**
 * @Author: DengJia
 * @Date: 2022/1/25 17:21
 * @Description: 集合相关操作工具类
 */

public class CollectionOpU {

    /**
     * @param a 集合a
     * @param b 集合b
     * @return 交集
     */
    public static <T> List<T> inter(List<T> a, List<T> b) {
        return a.stream()
                .filter(b::contains)
                .collect(toList());
    }

    public static <T, R> List<R> inter(List<T> a, List<T> b, Function<? super T, ? extends R> mapper) {
        List<? extends R> bProps = b.stream().map(mapper).collect(toList());
        return a.stream()
                .map(mapper)
                .filter(bProps::contains)
                .collect(toList());
    }

    /**
     * @param a 集合a
     * @param b 集合b
     * @return 并集不去重
     */
    public static <T> List<T> union(List<T> a, List<T> b) {
        List<T>
                apc = a.parallelStream().collect(toList()),
                bpc = b.parallelStream().collect(toList());
        apc.addAll(bpc);
        return apc;
    }


    /**
     * @param a 集合a
     * @param b 集合b
     * @return 并集去重
     */
    public static <T> List<T> unionByDistinct(List<T> a, List<T> b) {
        return union(a, b).stream()
                .distinct()
                .collect(toList());
    }

    public static <T, R> List<R> unionByDistinct(List<T> a, List<T> b, Function<? super T, ? extends R> mapper) {
        return union(a, b).stream()
                .map(mapper)
                .distinct()
                .collect(toList());
    }

    /**
     * 对于集合a、b，我们把集合{x∣x∈A,且x∉B}叫做a与b的差集。
     *
     * @param a 集合a
     * @param b 集合b
     * @return a与b的差集
     */
    public static <T> List<T> diff(List<T> a, List<T> b) {
        return a.stream()
                .filter(e -> !b.contains(e))
                .collect(toList());
    }

    public static <T, R> List<R> diff(List<T> a, List<T> b, Function<? super T, ? extends R> mapper) {
        List<? extends R> bProps = b.stream().map(mapper).collect(toList());
        return a.stream()
                .map(mapper)
                .filter(e -> !bProps.contains(e))
                .collect(toList());
    }
}
